/**
 * 
 */
package org.estock.config.xml;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.estock.common.model.task.Task;

/**
 * @author richard
 * 
 */
public class XMLUtil {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T> List<T> readXML(InputStream inputStream, Class<T> clazz) {
		List<T> list = new ArrayList<T>();
		try {
			SAXReader reader = new SAXReader();
			Document doc = reader.read(inputStream);
			Element root = doc.getRootElement();
			Element element = null;

			for (Iterator i = root.elementIterator(clazz.getSimpleName()); i.hasNext();) {
				element = (Element) i.next();
				T bean = (T) clazz.newInstance();
				
				List<Element> attrs = element.elements();
				for (int j = 0; j < attrs.size(); j++) {
					Element attr = attrs.get(j);
					String name = attr.attribute("name").getValue();
					String value = attr.attribute("value").getValue();
					invokeMethod(bean, name, value);
				}
				
				list.add(bean);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
	
	private static <T> void invokeMethod(T bean, String fieldName, Object value) throws Exception {
		Field myField = null;
		for (Field field : bean.getClass().getDeclaredFields()) {
			if (StringUtils.equals(fieldName, field.getName())) {
				myField = field;
				break;
			}
		}
		
		String name = myField.getName();
        name = name.substring(0, 1).toUpperCase() + name.substring(1);
        Method method = bean.getClass().getMethod("set" + name, myField.getType());
        
		String type = myField.getGenericType().toString();
		if (("class java.lang.String").equals(type)) {
			method.invoke(bean, String.valueOf(value));
        } else if (("class java.lang.Integer").equals(type) || "int".equals(type)) {
			method.invoke(bean, Integer.valueOf(String.valueOf(value)));
        } else if (("class java.lang.Boolean").equals(type) || "boolean".equals(type)) {
			method.invoke(bean, StringUtils.equalsIgnoreCase(type, "true"));
        }
	}
	
	///////// Testing method
	public static void main(String[] args) {
		List<Task> results = readXML(TaskDefs.getTaskDefInputSteam(), Task.class);
		System.out.println(results);
	}
	
}
